// #include <iostream>
// #include "log.hpp"
// #include "util.hpp"
// #include "mysql.hpp"
// #include "online_user.hpp"
// #include "session.hpp"
// #include "match.hpp"

// using namespace std;

// void testLog()
// {
//     setLogLevel(WARNING);
//     setLogFile("1.log");
//     Log(INFO, "aaaaaa");
//     Log(WARNING, "bbbb");
//     Log(FATAL, "cccc");
// }

// void testJson()
// {
//     Json::Value root;
//     Json::Value clild;
//     clild["class"]["zwz"] = "123456";
//     clild["class"]["hello"] = "world";
//     root["name"] = "zwz";
//     root["age"] = 19;
//     root["score"].append(100);
//     root["score"].append(120);
//     std::string str;
//     JsonUtil::Serialization(root, str);
//     std::cout << str << std::endl;
//     Json::Value DeRoot;
//     JsonUtil::DeSerialization(str, DeRoot);
//     std::cout << DeRoot["name"].asString() << " " << DeRoot["age"].asInt() << std::endl;
// }

// void testStr()
// {
//     std::string str("111,222,,,,,333");
//     std::vector<std::string> ret;
//     StrUtil::split(str, " ", ret);
//     for(auto e : ret)
//     {
//         std::cout << e << std::endl;
//     }
// }

// void testMysql()
// {
//     MysqlUserTable my;
//     Json::Value val;
//     // val["name"] = "lmh";
//     // val["password"] = "123456";
//     //my.insert(val);
//     my.lose(8);
//     std::cout << val["id"].asInt() << " " << val["name"].asString() << " "  \
//     << val["score"].asInt() << " "     \
//     << val["total_count"].asInt() << " " << val["win_count"].asInt() << std::endl;
// }

// void testOnlineUser()
// {
//     OnlineUser ou;
//     ou.addUserHall(1, websocketServer::connection_ptr());
//     if(ou.findInHall(1))
//         cout << "find" << endl;
//     else
//         cout << "nofind" << endl;
//     ou.deleteUserHall(1);
//     if(ou.findInHall(1))
//         cout << "find" << endl;
//     else
//         cout << "nofind" << endl;
// }


// void testSession()
// {
//     websocketServer svr;
//     svr.set_access_channels(websocketpp::log::alevel::none);
//     //初始化asio
//     svr.init_asio();
//     svr.set_reuse_addr(true);
//     SessionManage smg(&svr);
//     sessionPtr sptr = smg.createSession(3);
    
//     smg.setSessionExpireTime(sptr->getSid(), 500);
//     smg.setSessionExpireTime(sptr->getSid(), 5000);

//     //bind端口
//     svr.listen(8080);
//     //接收链接
//     svr.start_accept();
//     //启动服务
//     svr.run();
// }

// void testMatch()
// {
//     MysqlUserTable tb;
//     OnlineUser ol;
//     RoomManage rm(&tb, &ol);
//     Match match(&tb, &ol, &rm);
//     match.addPlayer(5);
//     match.addPlayer(6);
//     while(1)
//     {
//         sleep(1);
//     }
// }

// int main()
// {
//     testMatch();
//     return 0;
// }

#include <iostream>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>
#include "log.hpp"
#include "util.hpp"
#include "mysql.hpp"
#include "online_user.hpp"
#include "room.hpp"
#include "match.hpp"

typedef websocketpp::server<websocketpp::config::asio> websocketServer;

OnlineUser onlineuser;
MysqlUserTable mysqluser;
RoomManage room(&mysqluser, &onlineuser);
Match match(&mysqluser, &onlineuser, &room);

void httpHandler(websocketServer* svr, websocketpp::connection_hdl hdl)
{
    websocketServer::connection_ptr conn = svr->get_con_from_hdl(hdl);
    websocketpp::http::parser::request req = conn->get_request();
    std::cout << req.get_method().c_str() << std::endl;
    std::cout << req.get_uri().c_str() << std::endl;
    std::stringstream ss;
    ss << "<!doctype html><html><head>"
    << "<title>hello websocket</title><body>"
    << "<h1>hello websocketpp</h1>"
    << "</body></head></html>";

    conn->set_body(ss.str());
    conn->set_status(websocketpp::http::status_code::ok);
}

void OpenHandler(websocketServer* svr, websocketpp::connection_hdl hdl)
{
    std::cout << "websocket open" << std::endl;
    static int num = 8;

    websocketServer::connection_ptr conn = svr->get_con_from_hdl(hdl);
    onlineuser.addUserRoom(num, conn);
    onlineuser.addUserHall(num, conn);
    match.addPlayer(num);

    std::string out = std::to_string(num);
    out += " ";
    svr->send(hdl, out, websocketpp::frame::opcode::text);
    num++;
}

void CloseHandler(websocketServer* svr, websocketpp::connection_hdl hdl)
{
    std::cout << "websocket close" << std::endl;
}

void messageHandler(websocketServer* svr, websocketpp::connection_hdl hdl,  \
                    websocketServer::message_ptr msg)
{
    Json::Value root;
    JsonUtil::DeSerialization(msg->get_payload(), root);
    roomPtr rptr = room.findRoomFromUid(8);
    rptr->handlerRequest(root);
}

int main()
{
    //实例化server对象
    websocketServer svr;
    //设置日志
    svr.set_access_channels(websocketpp::log::alevel::none);
    //初始化asio
    svr.init_asio();
    svr.set_reuse_addr(true);
    //注册回调函数
    svr.set_http_handler(bind(httpHandler, &svr, std::placeholders::_1));
    svr.set_open_handler(bind(OpenHandler, &svr, std::placeholders::_1));
    svr.set_close_handler(bind(CloseHandler, &svr, std::placeholders::_1));
    svr.set_message_handler(bind(messageHandler, &svr, std::placeholders::_1, std::placeholders::_2));

    //bind端口
    svr.listen(8080);
    //接收链接
    svr.start_accept();
    //启动服务
    svr.run();


    return 0;
}